﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows;
using System.Windows.Media;
using System.Windows.Data;
using System.Windows.Documents;
using System.Text.RegularExpressions;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    /// <summary>
    /// 工作区管理器，用于处理工作区管理器中文件、目录、资源文件条目的增、删、刷新状态等操作。
    /// </summary>
    class WorkspaceManager
    {
        /// <summary>
        /// [构造方法]
        /// </summary>
        /// <param name="masterWindow">主窗口。</param>
        public WorkspaceManager(MainWindow masterWindow)
        {
            this.masterWindow = masterWindow;
        }

        private MainWindow masterWindow;
        /// <summary>
        /// 主窗口。
        /// </summary>
        public MainWindow MasterWindow
        {
            get { return this.masterWindow; }
        }

        /// <summary>
        /// 刷新工作区管理器。
        /// </summary>
        /// <param name="shouldSelPath">刷新后寻找指向这个路径的条目并选中该条目。</param>
        public void Refresh(string shouldSelPath)
        {
            if (this.masterWindow == null) return;

            TreeView treeView = this.masterWindow.tvWorkDirectory;
            treeView.Items.Clear();//全部清除。
            if (Directory.Exists(Globals.PathOfWorkspace) == false)
            {
                return;
            }

            WorkspaceTreeViewItem rootItem = new WorkspaceTreeViewItem(Globals.PathOfWorkspace, this.masterWindow) { IsExpanded = true, };
            treeView.Items.Add(rootItem);

            DirectoryInfo directoryInfo = new DirectoryInfo(Globals.PathOfWorkspace);

            FillWorkspaceTreeViewItem(directoryInfo, rootItem);

            if (string.IsNullOrWhiteSpace(shouldSelPath) == false && treeView.Items.Count > 0)
            {
                var shouldSelItem = FindWorkspaceTreeViewitemByFullPath(treeView.Items[0] as WorkspaceTreeViewItem, shouldSelPath);
                if (shouldSelItem == null) return;

                shouldSelItem.IsSelected = true;
                var parentItem = shouldSelItem.Parent as WorkspaceTreeViewItem;
                while (parentItem != null)
                {
                    parentItem.IsExpanded = true;
                    parentItem = parentItem.Parent as WorkspaceTreeViewItem;
                }
            }
        }

        /// <summary>
        /// [递归方法]在工作区管理器中寻找指向指定路径的条目。
        /// </summary>
        /// <param name="item">从哪个条目开始找。</param>
        /// <param name="fullPath">要查找的路径。</param>
        private WorkspaceTreeViewItem FindWorkspaceTreeViewitemByFullPath(WorkspaceTreeViewItem item, string fullPath)
        {
            if (item == null) return null;
            if (string.IsNullOrWhiteSpace(fullPath)) return null;

            if (item.FullPath == fullPath) return item;

            foreach (WorkspaceTreeViewItem wi in item.Items)
            {
                if (wi != null && wi.FullPath == fullPath) return wi;
                if (wi.HasItems)
                {
                    var subItem = FindWorkspaceTreeViewitemByFullPath(wi, fullPath);
                    if (subItem != null) return subItem;
                }
            }

            return null;
        }


        /// <summary>
        /// [递归方法]，根据当前目录路径填空相关条目到此目录对应的工作区条目中。
        /// </summary>
        /// <param name="directoryInfo">要生成条目的目录。</param>
        /// <param name="curItem">将生成的新条目添加到哪个条目作为子级。</param>
        void FillWorkspaceTreeViewItem(System.IO.DirectoryInfo curDirectoryInfo, WorkspaceTreeViewItem curItem)
        {
            if (curDirectoryInfo == null || curItem == null) return;

            List<WorkspaceTreeViewItem> tempItems = new List<WorkspaceTreeViewItem>();

            DirectoryInfo[] childDirectoryInfos = curDirectoryInfo.GetDirectories();
            if (childDirectoryInfos.Length > 0)
            {
                foreach (DirectoryInfo childDirectoryInfo in childDirectoryInfos)
                {
                    if (childDirectoryInfo.FullName.EndsWith("~")) continue;//以波形符结尾的目录是对应Markdown文件的图像存储目录。

                    bool isImage = (childDirectoryInfo.Name == "images~");
                    WorkspaceTreeViewItem newDirectoryItem =
                        new WorkspaceTreeViewItem(childDirectoryInfo.FullName, this.masterWindow) { IsExpanded = !isImage, };
                    tempItems.Add(newDirectoryItem);

                    //添加目录元文件相关资源文件
                    var metaDirectoryFileBaseName =
                        (childDirectoryInfo.FullName.EndsWith("\\") ? childDirectoryInfo.FullName : childDirectoryInfo.FullName + "\\")
                        + "_" + childDirectoryInfo.Name;
                    var metaDirectoryFile = metaDirectoryFileBaseName + ".md";
                    //if (File.Exists(metaDirectoryFile))
                    //{//去除此限制，只要存在资源文件就显示
                    var metaResourceDirectory = metaDirectoryFileBaseName + "~";
                    if (Directory.Exists(metaResourceDirectory))
                    {
                        DirectoryInfo resourceDirectoryInfo = new DirectoryInfo(metaResourceDirectory);
                        DirectoryInfo[] childResourceDirectoryInfos = resourceDirectoryInfo.GetDirectories();
                        foreach (var childResourceDirectoryInfo in childResourceDirectoryInfos)
                        {
                            //不显示资源文件夹本身，只显示资源文件夹下的子文件夹（例如：Images~）
                            if (childResourceDirectoryInfo.FullName.EndsWith("~") || childResourceDirectoryInfo.FullName.EndsWith("~\\"))
                            {
                                WorkspaceTreeViewItem newResourceSubDirectoryItem = new WorkspaceTreeViewItem(childResourceDirectoryInfo.FullName, this.masterWindow) { IsExpanded = false, };
                                newDirectoryItem.Items.Add(newResourceSubDirectoryItem);
                                var childResourceFileInfos = childResourceDirectoryInfo.GetFiles();
                                foreach (var childResourceFileInfo in childResourceFileInfos)
                                {
                                    WorkspaceTreeViewItem newResourceFileItem = new WorkspaceTreeViewItem(childResourceFileInfo.FullName, this.masterWindow);
                                    newResourceSubDirectoryItem.Items.Add(newResourceFileItem);
                                }
                            }
                        }
                    }
                    //}

                    FillWorkspaceTreeViewItem(childDirectoryInfo, newDirectoryItem);
                }
            }

            FileInfo[] childFileInfos = curDirectoryInfo.GetFiles();
            if (childFileInfos.Length > 0)
            {
                //再添加普通md文件。
                foreach (FileInfo childFileInfo in childFileInfos)
                {
                    if (childFileInfo.Extension.ToLower() == ".md")
                    {
                        if (childFileInfo.Name.ToLower() == ("_" + curDirectoryInfo.Name + ".md").ToLower()) continue;//已添加目录对应的特殊文件，此文件会被当作目录指向的文件进行处理。

                        WorkspaceTreeViewItem newFileItem = new WorkspaceTreeViewItem(childFileInfo.FullName, this.masterWindow) { IsExpanded = true, };
                        tempItems.Add(newFileItem);

                        //寻找此Md文件对应的资源文件夹。名称应为：文件名（去后缀名）+波形符
                        var resourceDirectory = childFileInfo.FullName.Substring(0, childFileInfo.FullName.Length - 3) + "~";
                        if (Directory.Exists(resourceDirectory))
                        {
                            DirectoryInfo resourceDirectoryInfo = new DirectoryInfo(resourceDirectory);
                            DirectoryInfo[] childResourceDirectoryInfos = resourceDirectoryInfo.GetDirectories();
                            foreach (var childResourceDirectoryInfo in childResourceDirectoryInfos)
                            {
                                //不显示资源文件夹本身，只显示资源文件夹下的子文件夹（例如：Images~）
                                if (childResourceDirectoryInfo.FullName.EndsWith("~") || childResourceDirectoryInfo.FullName.EndsWith("~\\"))
                                {
                                    WorkspaceTreeViewItem newResourceSubDirectoryItem = new WorkspaceTreeViewItem(childResourceDirectoryInfo.FullName, this.masterWindow) { IsExpanded = false, };
                                    newFileItem.Items.Add(newResourceSubDirectoryItem);
                                    var childResourceFileInfos = childResourceDirectoryInfo.GetFiles();
                                    foreach (var childResourceFileInfo in childResourceFileInfos)
                                    {
                                        WorkspaceTreeViewItem newResourceFileItem = new WorkspaceTreeViewItem(childResourceFileInfo.FullName, this.masterWindow);
                                        newResourceSubDirectoryItem.Items.Add(newResourceFileItem);
                                    }
                                }
                            }
                        }
                    }
                    else if (IsImageFile(childFileInfo.FullName))
                    {
                        //如果是图像文件，也不显示，其它文件不显示
                        WorkspaceTreeViewItem newFileItem = new WorkspaceTreeViewItem(childFileInfo.FullName, this.masterWindow) { IsExpanded = false, };
                        tempItems.Add(newFileItem);
                    }
                }
            }

            if (tempItems.Count > 0)
            {
                List<WorkspaceTreeViewItem> tmp2Items = new List<WorkspaceTreeViewItem>();
                List<WorkspaceTreeViewItem> tmp3Items = new List<WorkspaceTreeViewItem>();
                foreach (var i in tempItems)
                {
                    if (i.ShortName.StartsWith("_"))
                    {
                        tmp2Items.Add(i);
                    }
                    else tmp3Items.Add(i);
                }

                tmp2Items.Sort(new WorkspaceTreeViewItemCompare());
                tmp3Items.Sort(new WorkspaceTreeViewItemCompare());

                foreach (var i in tmp2Items)
                {
                    curItem.Items.Add(i);
                }

                foreach (var i in tmp3Items)
                {
                    curItem.Items.Add(i);
                }
            }
        }

        /// <summary>
        /// 检验指定目录是否有效的图像文件名。
        /// </summary>
        /// <param name="fullName"></param>
        /// <returns></returns>
        public static bool IsImageFile(string fullName)
        {
            if (string.IsNullOrEmpty(fullName)) return false;
            if (File.Exists(fullName) == false) return false;

            var lower = fullName.ToLower();

            if (lower.EndsWith(".jpg") || lower.EndsWith(".jpeg") || lower.EndsWith(".gif") ||
                lower.EndsWith(".png") || lower.EndsWith(".bmp") || lower.EndsWith(".ico")
                || lower.EndsWith(".tiff"))
                return true;

            return false;
        }
    }
}
